
package com.parking.status.sync.netty.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class TCPServer {

    @Autowired
    @Qualifier("serverBootstrap")
    private ServerBootstrap serverBootstrap;

    @Autowired
    @Qualifier("tcpServerSocketAddress")
    private InetSocketAddress tcpPort;

//    private ServerChannelInitializer serverChannelInitializer;

    private Channel serverChannel;

    public Channel getServerChannel() {
        return serverChannel;
    }

    public void setServerChannel(Channel serverChannel) {
        this.serverChannel = serverChannel;
    }

    public ServerBootstrap getServerBootstrap() {
        return serverBootstrap;
    }

    public void setServerBootstrap(ServerBootstrap serverBootstrap) {
        this.serverBootstrap = serverBootstrap;
    }

    public TCPServer() {}

//    public TCPServer(int tcpPort) {
//        this(tcpPort, 2, 2);
//    }
//
//    public TCPServer(int tcpPort, int bossCount, int workerCount) {
//        this(tcpPort, bossCount, workerCount, true, 100);
//    }
//
//    public TCPServer(int tcpPort, int bossCount, int workerCount, boolean keepAlive, int backlog) {
//        this.tcpPort = tcpPort;
//        this.bossCount = bossCount;
//        this.workerCount = workerCount;
//        this.keepAlive = keepAlive;
//        this.backlog = backlog;
//    }

//    @PostConstruct
    public void start() throws Exception {

        serverChannel =  serverBootstrap.bind(tcpPort).sync().channel().closeFuture().sync().channel();

    }

//    @SuppressWarnings("unchecked")
//    public ServerBootstrap bootstrap() {
//        serverChannelInitializer = new ServerChannelInitializer();
//        serverBootstrap = new ServerBootstrap();
//        serverBootstrap.group(bossGroup(), workerGroup())
//                .channel(NioServerSocketChannel.class)
//                .handler(new LoggingHandler(LogLevel.DEBUG))
//                .childHandler(serverChannelInitializer);
//        Map<ChannelOption<?>, Object> tcpChannelOptions = tcpChannelOptions();
//        Set<ChannelOption<?>> keySet = tcpChannelOptions.keySet();
//        for (@SuppressWarnings("rawtypes") ChannelOption option : keySet) {
//            serverBootstrap.option(option, tcpChannelOptions.get(option));
//        }
//        return serverBootstrap;
//    }


    @PreDestroy
    public void stop() throws Exception {
        serverChannel.close();
        serverChannel.parent().close();
    }

//    public Map<ChannelOption<?>, Object> tcpChannelOptions() {
//        Map<ChannelOption<?>, Object> options = new HashMap<ChannelOption<?>, Object>();
//        options.put(ChannelOption.SO_KEEPALIVE, keepAlive);
//        options.put(ChannelOption.SO_BACKLOG, backlog);
//        return options;
//    }

//    public NioEventLoopGroup bossGroup() {
//        return new NioEventLoopGroup(bossCount);
//    }
//
//    public NioEventLoopGroup workerGroup() {
//        return new NioEventLoopGroup(workerCount);
//    }
//
//    public InetSocketAddress tcpPort() {
//        return new InetSocketAddress(tcpPort);
//    }
//
//    public ChannelRepository channelRepository() {
//        return new ChannelRepository();
//    }
}
